/*********************************************Copyright (c)***********************************************
** 
**
**--------------File Info---------------------------------------------------------------------------------
** File name:               none
** Latest modified Date:    none
** Latest Version:          none
** Descriptions:            none
**
**--------------------------------------------------------------------------------------------------------
** Created by:              Huangshihong
** Created date:            2021-05-26
** Version:                 V1.00
** Descriptions:            The original version
**
**--------------------------------------------------------------------------------------------------------
** Modified by:             
** Modified date:           
** Version:                 
** Descriptions:            
**
*********************************************************************************************************/

/********************************************************************************************************
** Includes
*********************************************************************************************************/
#include "pca9535.h"
#include "delay.h"
#include "myiic1.h"
#include "myiic2.h"
#include "log.h"

/********************************************************************************************************
** Defined
*********************************************************************************************************/
#ifdef  LOG_TAG
	#undef  LOG_TAG
#endif
#define LOG_TAG pca9535
LOG_REGIST();


/********************************************************************************************************
** Global variable
*********************************************************************************************************/
iic_ops iic1_hander = {
    .iic_init = IIC1_Init,
    .iic_read_byte = IIC1_Read_Byte,
    .iic_send_ack = IIC1_Ack,
    .iic_send_byte = IIC1_Send_Byte,
    .iic_send_nack = IIC1_NAck,
    .iic_start = IIC1_Start,
    .iic_stop = IIC1_Stop,
    .iic_wait_ack = IIC1_Wait_Ack  
};

iic_ops iic2_hander = {
    .iic_init = IIC2_Init,
    .iic_read_byte = IIC2_Read_Byte,
    .iic_send_ack = IIC2_Ack,
    .iic_send_byte = IIC2_Send_Byte,
    .iic_send_nack = IIC2_NAck,
    .iic_start = IIC2_Start,
    .iic_stop = IIC2_Stop,
    .iic_wait_ack = IIC2_Wait_Ack  
};

/*********************************************************************************************************
** Function name:      none
** Descriptions:       none
** input parameters:   none
** output parameters:  none
** Returned value:     none
** Created by:         Huangshihong
** Created Date:       2021-05-28
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
*********************************************************************************************************/
u8 pca9535_check(iic_ops *iic_hander,u8 dev_addr)
{
    u8 ret = 0;
    iic_hander->iic_init();
    iic_hander->iic_start();
    iic_hander->iic_read_byte(dev_addr);
    ret = iic_hander->iic_wait_ack();
    iic_hander->iic_stop();
    return ret;
}

u8 pca9535_read_byte(iic_ops *iic_hander,u8 dev_addr,u8 reg_addr)
{	
    u8 temp = 0;
    iic_hander->iic_start();
    iic_hander->iic_send_byte(dev_addr|0x00);
    iic_hander->iic_wait_ack();
    iic_hander->iic_send_byte(reg_addr);
    iic_hander->iic_wait_ack();
    iic_hander->iic_start();
    iic_hander->iic_send_byte(dev_addr|0x01);
    iic_hander->iic_wait_ack();
    temp = iic_hander->iic_read_byte(0);
    iic_hander->iic_stop();
    return temp;
}

void pca9535_write_byte(iic_ops *iic_hander,u8 dev_addr,u8 reg_addr,u8 data)
{		
    iic_hander->iic_start();
    iic_hander->iic_send_byte(dev_addr|0x00);
    iic_hander->iic_wait_ack();
    iic_hander->iic_send_byte(reg_addr);
    iic_hander->iic_wait_ack();
    iic_hander->iic_send_byte(data);
    iic_hander->iic_wait_ack();
    iic_hander->iic_stop();
    delay_ms(10);
}

void pca9535_write_bit(iic_ops *iic_hander,u8 dev_addr,u8 reg_addr,u8 bit,u8 sta)
{
    u8 data;
    data = pca9535_read_byte(iic_hander,dev_addr,reg_addr);
    if(sta==0)data&=~(1<<bit);     
    else data|=1<<bit;
    pca9535_write_byte(iic_hander,dev_addr,reg_addr,data);
}

u8 pca9535_read_bit(iic_ops *iic_hander,u8 dev_addr,u8 reg_addr,u8 bit)
{
    u8 data;
    data = pca9535_read_byte(iic_hander,dev_addr,reg_addr);
    if(data&(1<<bit))return 1;
    else return 0;  
}

void pca9535_a_init(void)
{
    //pca9535 config,p0 and p1 default input
    if (pca9535_check(&iic1_hander,PCA9535_A_DEV_ADDR)) {
        log_info("pca9535_a check fail !\r\n");
    } 
    pca9535_read_byte(&iic1_hander,PCA9535_A_DEV_ADDR,TCA9535_INPUT_PORT0_REG);
    pca9535_read_byte(&iic1_hander,PCA9535_A_DEV_ADDR,TCA9535_INPUT_PORT1_REG);
}

void pca9535_b_init(void)
{
    //pca9535 config,p0 and p1 default input
    if (pca9535_check(&iic1_hander,PCA9535_B_DEV_ADDR)) {
        log_info("pca9535_b check fail !\r\n");
    } 

    pca9535_write_byte(&iic1_hander,PCA9535_B_DEV_ADDR,TCA9535_CONFIG_PORT0_REG,0x00);
    pca9535_write_byte(&iic1_hander,PCA9535_B_DEV_ADDR,TCA9535_OUTPUT_PORT0_REG,0x00);
    pca9535_write_byte(&iic1_hander,PCA9535_B_DEV_ADDR,TCA9535_CONFIG_PORT0_REG,0xff);
    pca9535_write_byte(&iic1_hander,PCA9535_B_DEV_ADDR,TCA9535_CONFIG_PORT1_REG,0x03);
}

void pca9535_c_init(void)
{
    //pca9535 config,p0 and p1 default input
    if (pca9535_check(&iic1_hander,PCA9535_C_DEV_ADDR)) {
        log_info("pca9535_c check fail !\r\n");
    } 

    pca9535_write_byte(&iic1_hander,PCA9535_C_DEV_ADDR,TCA9535_CONFIG_PORT0_REG,0x00);
    pca9535_write_byte(&iic1_hander,PCA9535_C_DEV_ADDR,TCA9535_OUTPUT_PORT0_REG,0x00);
    pca9535_write_byte(&iic1_hander,PCA9535_C_DEV_ADDR,TCA9535_CONFIG_PORT0_REG,0xff);
    pca9535_write_byte(&iic1_hander,PCA9535_C_DEV_ADDR,TCA9535_CONFIG_PORT1_REG,0x7f);
}

void pca9535_d_init(void)
{
    //pca9535 config,p0 and p1 default input
    if (pca9535_check(&iic2_hander,PCA9535_D_DEV_ADDR)) {
        log_info("pca9535_d check fail !\r\n");
    } 
    pca9535_read_byte(&iic2_hander,PCA9535_D_DEV_ADDR,TCA9535_INPUT_PORT0_REG);
    pca9535_read_byte(&iic2_hander,PCA9535_D_DEV_ADDR,TCA9535_INPUT_PORT1_REG);
}

void pca9535_int_init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    //pca9535_a interrupt pin initialize
    __HAL_RCC_GPIOB_CLK_ENABLE();

    GPIO_Initure.Pin=PCA9535_A_INT_PIN;               
    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING;     
    GPIO_Initure.Pull=GPIO_PULLUP;
    HAL_GPIO_Init(PCA9535_A_INT_PORT,&GPIO_Initure);

    HAL_NVIC_SetPriority(EXTI9_5_IRQn,7,0);       
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); 

    //pca9535_b interrupt pin initialize
//    __HAL_RCC_GPIOD_CLK_ENABLE();

//    GPIO_Initure.Pin=PCA9535_B_INT_PIN;               
//    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING;     
//    GPIO_Initure.Pull=GPIO_PULLUP;
//    HAL_GPIO_Init(PCA9535_B_INT_PORT,&GPIO_Initure);

//    HAL_NVIC_SetPriority(EXTI4_IRQn,7,0);       
//    HAL_NVIC_EnableIRQ(EXTI4_IRQn); 

    //pca9535_c interrupt pin initialize
//    __HAL_RCC_GPIOA_CLK_ENABLE();

//    GPIO_Initure.Pin=PCA9535_C_INT_PIN;               
//    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING;     
//    GPIO_Initure.Pull=GPIO_PULLUP;
//    HAL_GPIO_Init(PCA9535_C_INT_PORT,&GPIO_Initure);

//    HAL_NVIC_SetPriority(EXTI9_5_IRQn,7,0);       
//    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); 

    //pca9535_d interrupt pin initialize
    __HAL_RCC_GPIOC_CLK_ENABLE();

    GPIO_Initure.Pin=PCA9535_D_INT_PIN;               
    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING;     
    GPIO_Initure.Pull=GPIO_PULLUP;
    HAL_GPIO_Init(PCA9535_D_INT_PORT,&GPIO_Initure);

    HAL_NVIC_SetPriority(EXTI15_10_IRQn,7,0);       
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); 
}

u16 pca9535_a_callback_func(void)
{
    return (u16)((pca9535_read_byte(&iic1_hander,PCA9535_A_DEV_ADDR,TCA9535_INPUT_PORT0_REG) << 0) |
                (pca9535_read_byte(&iic1_hander,PCA9535_A_DEV_ADDR,TCA9535_INPUT_PORT1_REG) << 8));
}

u16 pca9535_d_callback_func(void)
{
    return (u16)((pca9535_read_byte(&iic2_hander,PCA9535_D_DEV_ADDR,TCA9535_INPUT_PORT0_REG) << 0) |
                (pca9535_read_byte(&iic2_hander,PCA9535_D_DEV_ADDR,TCA9535_INPUT_PORT1_REG) << 8));
}

    
